#include<iostream>
#include<vector>
#include<unistd.h>
#include<pthread.h>

using namespace std;

#define NUM 3

//int *p=NULL; 

//int g_val=100;
__thread int g_val=100;//线程的局部存储
//只能定义内置类型，不能修饰自定义类型
__thread unsigned int number=0;

//创建一个线程需要传参
struct threadData
{
    string tid;
    string threadname;
};

//转成16进制
string toHex(pthread_t tid)
{
    //设置初始值
    char buffer[128];
    snprintf(buffer,sizeof(buffer),"0x%x",tid);
    return buffer;
}

//初始化线程函数
void InitThreadData(threadData *td,int number)
{
    td->threadname="thread-"+to_string(number);//thread-0
}

//所有的线程都是执行这个函数吗？
void *threadRoutine(void *args)
{
    int test_i=0;
    threadData *td=static_cast<threadData*>(args);
    //if(td->threadname=="thread-2") p=&test_i;
    //int number=pthread_self();
    //int pid=getpid();

    int i=0;
    while(i<10)
    {
        cout<<"pid: "<<getpid()
        <<", tid:"<<toHex(pthread_self())
        <<", threadname:"<<td->threadname
        <<"test_i:"<<test_i
        <<",&test_i:"<<&test_i
        <<toHex((pthread_t)&test_i)
        <<",g_val:"<<g_val
        <<",&g_val"<<&g_val
        <<endl;

        sleep(1);
        i++;
        g_val++;//全局变量可以被所有线程看到并且访问
        //test_i++;
    }
    delete td;
    return nullptr;
}

int main()
{
    //我想创建一批线程
    vector<pthread_t> tids;
    for(int i=0;i<NUM;i++)
    {
        //不可以这样创建，td变量在for循环中，属于主线程的栈中
        //如果for循环结束，那传参就可能会引起野指针的访问，因为这里的td会被释放掉
        //如果定义全局变量也是可以的。
        //threadData td;
        //td.threadname=;
        //td.tid=;

        pthread_t tid;//创建线程
        //堆上独占了一小块空间，我自己用
        //所有线程共享堆空间，线程是一家人，资源可以互相访问
        threadData* td=new threadData;

        InitThreadData(td,i);//对线程进行初始化

        pthread_create(&tid,nullptr,threadRoutine,td);
        tids.push_back(tid);
    }

    //sleep(1);
    //cout<<"main thread get a thread local value,val:"<<*p
    //<<",&val"<<p<<endl;
    //每个线程都会有属于自己的栈结构
    //线程和栈上的数据，也是可以被其他线程看到并且访问的

    for(int i=0;i<tids.size();i++)
    {
        pthread_join(tids[i],nullptr);//线程等待
    }

    return 0;
}